/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core/threads
// Copyright (c) 2014.  All Rights Reserved
//
// File:		AEThreadPool.h
// Author:		Gianluca Belardelli
// Date:		12/03/2014
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AETHREADPOOL_H_
#define _AETHREADPOOL_H_

//#include <queue>
typedef AETQueue< AEThreadWorkItem * > AEWorkItemsQueue;

class AE_DLLIMPEXP AEThreadPool
{
// Members
protected:
	AEThread			**m_lpWorkerThreads;
	AEUINT32			*m_lpWorkerThreadIds;
	AEThreadContext		*m_lpThreadContexts;

	AESemaphore			*m_lpWorkQueueSemaphore;	

	AEUINT32			m_uiNumThreads;
	AEUINT32			m_uiNumActiveThreads;
	AEUINT32			m_uiCallbackCountdown;
	
	AEBOOL32			m_bInitialized;
	AEWorkItemsQueue	*m_lpWorkQueue;
	
	AECriticalSection	m_csQueueSW;

// Methods
private:
	static AEUINT32 AESTDCALL workerThreadProc( void *lpContext );

public:
	AE_DECLARE_NONVIRTUAL_CLASS_ALLOCATOR( TOBEDEFINED, AEThreadPool );
	AEThreadPool( void );
	~AEThreadPool( void );

	void Initialize( AEUINT32 uiNumThreads = 0 );
	void Shutdown( void );

	void EnqueueWorkItem( AEThreadWorkItem *lpItem );
	AEThreadWorkItem *RemoveWorkItem( void );

	void PrimaryThreadExecute( AEThreadContext::AEThreadCallback lpfnCallback, void *lpData );
	void PopAndProcessWorkItem( AEBOOL32 bProcess = TRUE );
	
	void SetActiveThreadCount( AEUINT32 uiCount );

	AEUINT32 GetThreadCount( void ) { return m_uiNumThreads; }
	AEUINT32 GetActiveThreadCount( void ) { return m_uiNumActiveThreads; }
};

#endif // _AETHREADPOOL_H_
